<?php

/*
 * This file is part of the Dektrium project
 *
 * (c) Dektrium project <http://github.com/dektrium>
 *
 * For the full copyright and license information, please view the LICENSE.md
 * file that was distributed with this source code.
 */

namespace yiike\user\clients;

use Yii;
use yii\authclient\OAuth2;

/**
 * @author Dmitry Erofeev <dmeroff@gmail.com>
 */
class Weixin extends OAuth2 implements \dektrium\user\clients\ClientInterface {

    public $access_token;
    
    public $openid;

    /**
     * @inheritdoc
     */
    public $authUrl    = 'https://open.weixin.qq.com/connect/qrconnect';

    /**
     * @inheritdoc
     */
    public $tokenUrl   = 'https://api.weixin.qq.com/sns/oauth2/access_token';

    /**
     * @inheritdoc
     */
    public $apiBaseUrl = 'https://api.weixin.qq.com';

    /**
     * @inheritdoc
     */
    public function init() {
        parent::init();
        if ($this->scope === null) {
            $this->scope = implode(' ', [
                'snsapi_login',
            ]);
        }
    }

    /** @inheritdoc */
    public function getEmail() {
        return null;
    }

    /** @inheritdoc */
    public function getUsername() {
        return null;
    }

    /**
     * @inheritdoc
     */
    protected function defaultNormalizeUserAttributeMap() {
        return [
            'id'       => 'openid',
            'username' => 'nickname',
        ];
    }

    /**
     * @inheritdoc
     */
    public function buildAuthUrl(array $params = []) {
        $authState       = $this->generateAuthState();
        $this->setState('authState', $authState);
        $params['state'] = $authState;
        $params['appid'] = $this->clientId;
        return parent::buildAuthUrl($params);
    }

    /**
     * @inheritdoc
     */
    public function getAccessToken() {
        $params = ['access_token' => $this->access_token, 'openid' => $this->openid, 'expires_in' => 7200];
        $config = [ 'class' => \yii\authclient\OAuthToken::className(), 'tokenParamKey' => 'access_token', 'params' => $params];        
        $token  = Yii::createObject($config);
        $this->setAccessToken($token);
        return $token;
    }

    /**
     * @inheritdoc
     */
    protected function apiInternal($accessToken, $url, $method, array $params, array $headers) {
        $params['access_token'] = $accessToken->getToken();
        $params['openid']       = $accessToken->getParam('openid');
        $params['lang']         = 'zh_CN ';
        $req = $this->sendRequest($method, $url, $params, $headers);
        if (isset($req['errcode'])) {
            throw new \yii\base\Exception('Access token is error', 100038);
        }
        return $req;
    }

    /**
     * @inheritdoc
     */
    protected function initUserAttributes() {
        return $this->api('sns/userinfo');
    }

    /**
     * @inheritdoc
     */
    protected function defaultReturnUrl() {
        $params    = $_GET;
        unset($params['code']);
        unset($params['state']);
        $params[0] = Yii::$app->controller->getRoute();

        return Yii::$app->getUrlManager()->createAbsoluteUrl($params);
    }

    /**
     * Generates the auth state value.
     * @return string auth state value.
     */
    protected function generateAuthState() {
        return sha1(uniqid(get_class($this), true));
    }

    /**
     * @inheritdoc
     */
    protected function defaultName() {
        return 'weixin';
    }

    /**
     * @inheritdoc
     */
    protected function defaultTitle() {
        return '微信';
    }

    /**
     * @inheritdoc
     */
    protected function defaultViewOptions() {
        return [
            'popupWidth'  => 800,
            'popupHeight' => 500,
        ];
    }

}
